/*
 * Copyright 2008 Sebastian Köhler
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package calyriumdc.gui;

import calyriumdc.DownloadManager;
import calyriumdc.FileListParser;
import calyriumdc.event.FileListParserEvent;
import calyriumdc.event.FileListParserListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.xml.stream.XMLStreamException;
import org.jdesktop.application.Action;

public class FileListPanel extends javax.swing.JPanel {

    private static final Icon LEAF = new ImageIcon(FileListPanel.class.getResource("resources/treeopen16.png"));
    private static final Icon OPEN = new ImageIcon(FileListPanel.class.getResource("resources/treeopen16.png"));
    private static final Icon CLOSED = new ImageIcon(FileListPanel.class.getResource("resources/treeclosed16.png"));
    private String nick;
    private int id;
    private FileListParser parser;
    private SortedTreeModel treemodel;
    private DefaultTableModel tablemodel;
    private DefaultMutableTreeNode root;

    /** Creates new form FileListPanel */
    public FileListPanel(String filelist, String nick, int id) {
        this.nick = nick;
        this.id = id;
        parser = new FileListParser(filelist);
        root = new DefaultMutableTreeNode("/");
        treemodel = new SortedTreeModel(root, new TreeNodeComparator());
        initComponents();
        DefaultTreeCellRenderer ren = new DefaultTreeCellRenderer();
        ren.setClosedIcon(CLOSED);
        ren.setLeafIcon(LEAF);
        ren.setOpenIcon(OPEN);
        jTree1.setCellRenderer(ren);
        jTree1.setModel(treemodel);
        tablemodel = (DefaultTableModel) jTable1.getModel();
        treemodel.setRoot(root);
        parser.addFileListParserListener(new FileListParserListener() {

            DefaultMutableTreeNode top = root;

            public void newElement(final FileListParserEvent evt) {
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {

                        public void run() {
                            if (evt.getState() == FileListParserEvent.FILE) {
                                String[] row = new String[3];
                                row[0] = evt.getName();
                                row[1] = evt.getSize();
                                row[2] = evt.getTth();
                                tablemodel.addRow(row);
                            }
                            if (evt.getState() == FileListParserEvent.DIRECTORY) {
                                DefaultMutableTreeNode node = new DefaultMutableTreeNode(evt.getName());
                                top.add(node);
                                treemodel.reload(top);
                                top = node;
                            }
                            if (evt.getState() == FileListParserEvent.DIRECTORY_CLOSED) {
                                if (top.getParent() == null) {
                                    top = root;
                                } else {
                                    top = (DefaultMutableTreeNode) top.getParent();
                                }
                            }
                        }
                    });
                } catch (InterruptedException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        jTree1.addTreeSelectionListener(new TreeSelectionListener() {

            public void valueChanged(TreeSelectionEvent evt) {
                if (evt.isAddedPath()) {
                    startFileParser(evt.getPath().getPath());
                }
            }
        });
        startDirectoryParser();
    }

    private void startFileParser(final Object[] path) {
        new Thread(new Runnable() {

            public void run() {
                try {
                    parser.parseFiles(path);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (XMLStreamException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();
    }

    private void startDirectoryParser() {
        new Thread(new Runnable() {
            public void run() {
                try {
                    parser.parseDirectories();
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (XMLStreamException ex) {
                    Logger.getLogger(FileListPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();
    }

    @Action
    public void download() {
        int[] selectedrows = jTable1.getSelectedRows();
        for (int i : selectedrows) {
            String filename = (String) jTable1.getValueAt(i, 0);
            String size = (String) jTable1.getValueAt(i, 1);
            String tth = (String) jTable1.getValueAt(i, 2);
            if (nick == null) {
                DownloadManager.getInstance().addDownload(filename, size, tth);
            //TODO: Mit DownloadManager suche nach tth starten
            } else {
                System.out.println(nick + " " + filename + " " + size + "" + tth + " " + id);
                DownloadManager.getInstance().addDownload(nick, filename, size, tth, id);
            //TESTING://TODO: ConnectToMe aus der Gui in den downloadmanager verlagern
            }
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPopupMenu1 = new javax.swing.JPopupMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTree1 = new javax.swing.JTree();

        jPopupMenu1.setName("jPopupMenu1"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(calyriumdc.CalyriumDC.class).getContext().getActionMap(FileListPanel.class, this);
        jMenuItem1.setAction(actionMap.get("download")); // NOI18N
        jMenuItem1.setName("jMenuItem1"); // NOI18N
        jPopupMenu1.add(jMenuItem1);

        setName("Form"); // NOI18N

        jSplitPane1.setDividerLocation(151);
        jSplitPane1.setName("jSplitPane1"); // NOI18N

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        jTable1.setAutoCreateRowSorter(true);
        jTable1.setComponentPopupMenu(jPopupMenu1);
        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Name ", "Size ", "TTH"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTable1.setName("jTable1"); // NOI18N
        jScrollPane2.setViewportView(jTable1);
        jTable1.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        jSplitPane1.setRightComponent(jScrollPane2);

        jScrollPane3.setName("jScrollPane3"); // NOI18N

        jTree1.setName("jTree1"); // NOI18N
        jScrollPane3.setViewportView(jTree1);

        jSplitPane1.setLeftComponent(jScrollPane3);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JPopupMenu jPopupMenu1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTree jTree1;
    // End of variables declaration//GEN-END:variables
}
